import Pbf from 'pbf'
import geobuf from 'geobuf'
import TileLayer from 'ol/layer/Tile'
import { deBase64 } from '@/utils/decode'
import GeoJSON from 'ol/format/GeoJSON.js'
import VectorLayer from 'ol/layer/Vector.js'
import olLayerGroup from 'ol/layer/Group.js'
import VectorSource from 'ol/source/Vector.js'
import { Group as LayerGroup,Heatmap  } from 'ol/layer.js'
import VectorTileLayer from 'ol/layer/VectorTile.js'
import VectorImageLayer from 'ol/layer/VectorImage.js'
import { Fill, Stroke, Style, Text, Circle, Icon } from 'ol/style.js'
// import Circle from 'ol/geom/Circle';
import Feature from 'ol/Feature'
import Point from 'ol/geom/Point'
import { fromLonLat, toLonLat, transformExtent, transform } from 'ol/proj'
import { TileWMS } from 'ol/source'
import Overlay from 'ol/Overlay'
import { Polygon, LineString, Circle as CircleGeometry } from 'ol/geom'
import { Draw } from 'ol/interaction'
import { getLength, getArea, getDistance } from 'ol/sphere'
import { unByKey } from 'ol/Observable'
import config from '../../config/index'
import proj4 from 'proj4';
import { Projection } from 'ol/proj';
import { register } from 'ol/proj/proj4';
import * as onemap from '../onemap';
import {useMapStoreStore} from '../../stores/index'
const store = useMapStoreStore()
var MapColors = [
  'rgba(199, 252, 229, 0.2)',
  'rgba(252, 212, 230, 0.2)',
  'rgba(195, 179, 252, 0.2)',
  'rgba(230, 252, 198, 0.2)',
  'rgba(252, 184, 196, 0.2)',
  'rgba(252, 223, 179, 0.2)',
  'rgba(212, 252, 250, 0.2)',
  'rgba(252, 179, 249, 0.2)',
  'rgba(199, 231, 252, 0.2)',
  'rgba(245, 204, 252, 0.2)',
  'rgba(189, 252, 190, 0.2)',
  'rgba(252, 182, 219, 0.2)',
  'rgba(212, 217, 252, 0.2)',
  'rgba(252, 216, 202, 0.2)',
  'rgba(252, 247, 204, 0.2)',
  'rgba(179, 240, 252, 0.2)'
]

const MapStyle = function (options, feature) {
  var name = ''
  var colorIndex = 0
  if (options) {
    name = feature.get(options.text)
    colorIndex = parseInt(feature.get(options.colorIndex)) % MapColors.length
  }

  return new Style({
    fill: new Fill({
      color: MapColors[colorIndex]
    }),
    stroke: new Stroke({
      color: 'rgba(252, 184, 196, 0.9)',
      width: 2,
      lineDash: [20, 10, 20, 10]
    }),
    text: new Text({
      text: name, // 从 title 属性中获取文本内容
      offsetY: 0, // 文本垂直偏移量
      fill: new Fill({
        color: 'rgba(64, 64,64,0.5)' // 文本颜色
      }),
      stroke: new Stroke({
        color: 'white', // 设置描边颜色为白色
        width: 2 // 设置描边宽度为2像素
      }),
      font: '16px sans-serif' // 字体样式
    }) // 将文本样式应用到点要素
  })
}

const LoadBaseLayers = async (options) => {
  var ol2d = options.ol2d
  var allLayers = options.allLayers
  var parentLayer = options.parentLayer

  allLayers.forEach((item) => {
    var tmphlLayer
    if (item.type == 'VectorImageLayer') {
      tmphlLayer = new VectorImageLayer({
        id: item.id,
        name: item.name,
        declutter: true,
        visible: item.visible
      })
    } else if (item.type == 'TileLayer') {
      tmphlLayer = new TileLayer({
        id: item.id,
        name: item.name,
        visible: item.visible
      })
    } else if (item.type == 'VectorLayer') {
      tmphlLayer = new VectorLayer({
        id: item.id,
        name: item.name,
        declutter: true,
        visible: item.visible
      })
    } else if (item.type == 'VectorTileLayer') {
      tmphlLayer = new VectorTileLayer({
        id: item.id,
        name: item.name,
        declutter: true,
        visible: item.visible
      })
    } else if (item.type == 'GroupLayer') {
      tmphlLayer = new LayerGroup({
        id: item.id,
        name: item.name,
        visible: item.visible
      })

      var tmpOptions = {
        ol2d: options.ol2d,
        allLayers: item.childrens,
        parentLayer: tmphlLayer
      }
      LoadBaseLayers(tmpOptions)
    }
    if (parentLayer) {
      parentLayer.getLayers().push(tmphlLayer)
    } else {
      ol2d.addLayer(tmphlLayer)
    }
  })
}

//加载表数据
const AddMapLayer = async (options) => {
  var query = options.query

  // var tmpSource = await geopub.listGeoByTable(query);
  // let resultJson = geobuf.decode(new Pbf(deBase64(tmpSource.data.geobuf)));

  // options["geojson"] = resultJson;
  // var tmpLayer = await AddGeoJsonLayer(options);
  // return tmpLayer;
}

//加载geojson数据；
const AddGeoJsonLayer = async (options) => {
  var ol2d = options.ol2d
  var layerid = options.id //"xianlayer";
  var tmpStyle = options.style
  var tmpStyleExt = options.styleExt

  var isFit = options.isFit

  let resultJson = options.geojson

  if (layerid == 'shenglayer') {
    console.info('加载___shenglayer', layerid)
  }

  var tmpLayer = ol2d.getLayerById(layerid)
  if (tmpLayer) {
    //设定样式
    if (tmpStyle) {
      tmpLayer.setStyle(tmpStyle)
    } else {
      //使用默认的样式
      tmpLayer.setStyle(MapStyle.bind(null, tmpStyleExt))
    }

    tmpLayer.setSource(
      new VectorSource({
        features: new GeoJSON().readFeatures(resultJson)
      })
    )
    //

    if (isFit) {
      ol2d.getView().fit(tmpLayer.getSource().getExtent(), {
        padding: [50, 50, 50, 50], // 可选的填充，以确保要素不会被地图边缘截断
        duration: 1000 // 动画持续时间（以毫秒为单位）
      })
    }
    return tmpLayer
  }
  return null
}

const createPoint = (option) => {
  const vectorSource = new VectorSource()
  // 创建点的 Feature
  const pointFeature = new Feature({
    geometry: new Point(fromLonLat(option.poi)),
    data: option.data || {},
    type: option.type || ''
  }) // 替换为实际的经纬度
  // const pointFeature = new Feature(new Point(( option.poi ))); // 替换为实际的经纬度
  // 配置圆形样式
  const style = new Style({
    fill: new Fill({
      color: option.color || 'rgba(255, 0, 0, 0.2)' // 填充颜色
    }),
    image: new Icon({
      src: '/static/icon/poi.png'
    })
  })

  pointFeature.setStyle(style)
  vectorSource.addFeature(pointFeature)

  let vectorLayer = new VectorLayer({
    // layerOrder:99999,
    // type:"layer1",
    source: vectorSource
  })

  map.addLayer(vectorLayer)
  // 设置地图的中心点和缩放级别
  map.getView().setCenter(fromLonLat(option.poi))
  map.getView().setZoom(14)

  const edit = (option) => {
    const newpointFeature = new Point(fromLonLat(option.poi)) // 替换为实际的经纬度
    pointFeature.setGeometry(newpointFeature) // 更新Feature的几何属性
    pointFeature.set('data', option.data)
    map.getView().setCenter(fromLonLat(option.poi))
    map.getView().setZoom(14)
  }
  const del = () => {
    map.getLayers().remove(vectorLayer)
    vectorLayer = null
  }
  return { vectorLayer, edit, del }
}

// 重写 projection4490
export const projection = new Projection({
  code: 'EPSG:4490',
  units: 'degrees',
  axisOrientation: 'neu'
});
projection.setExtent([73.62004852294922, 18.16888427734375, 134.76846313476562, 53.553741455078125]);

 const init4490 = () => {
  // 注册投影定义
  proj4.defs('EPSG:4490', '+proj=longlat +ellps=GRS80 +no_defs +type=crs');
  register(proj4);
}


export let mapFlag = {};
export let mapLayers = {};
export const clearFlag = ()=>{
  mapFlag = {};
  mapLayers = {};
}

const addMapLayer = (layerUrl, layerCode, layerOrder, eqid, isfilter, version) => {
  // if (isfilter && layerCode == "kspgyxcm") {
  //   loadEarthQuakeYXC(eqid, layerCode, version)
  //   return
  // }

  if (mapFlag[layerCode]) {
    showMap(layerCode);
    return
  }
  
  // eqid = "d2c1c87b54ce4e7f8e07d676d7be72fe"
  const params = {
    LAYERS: layerUrl,
    FORMAT: 'image/png',
  }
  const tsparams = {
    LAYERS: layerUrl,
    FORMAT: 'image/png',
    layerDefs: JSON.stringify({
      ['0.1']: `earth_quake_id='${eqid}' AND version='${version}'`,
      ['0.0']: `earth_quake_id='${eqid}' AND version='${version}'` ,
    })
  }
  if(layerCode == "zxzzzj"){
    tsparams.layerDefs = JSON.stringify({
      ['0.0']: `earthquake_id='${eqid}'`
    })
  }
  
  if( layerCode == "kspgyxcm"){
    tsparams.layerDefs = JSON.stringify({
      ['0.2']: `earth_quake_id='${eqid}' AND version='${version}'`,
      ['0.1']: `earth_quake_id='${eqid}' AND version='${version}'`,
      ['0.0']: `earth_quake_id='${eqid}'  AND version='${version}'` 
    })
  }

  if(layerCode == "kspgyxcx"  ){
    tsparams.layerDefs = JSON.stringify({
      ['0.1']: `earth_quake_id='${eqid}' AND version='${version}'`,
      ['0.0']: `earth_quake_id='${eqid}' AND version='${version}'` 
    })
  }


 if(layerCode == "zzj1" || layerCode == "zzj0"){
  tsparams.layerDefs = JSON.stringify({
    ['0.1']: `earthquake_id='${eqid}'`,
    ['0.0']: `earthquake_id='${eqid}'`,
  
  })
}
  const supermaplayer = new TileLayer({
    id: layerCode,
    zIndex: layerOrder,
    source: new TileWMS({
      url: config.SUPERMAPURL + layerUrl,
      projection: projection,
      params: isfilter ? tsparams : params,
      crossOrigin: 'anonymous', // 跨域请求设置
    })
  })
  mapFlag[layerCode] = true;
  mapLayers[layerCode] = supermaplayer;
  map.addLayer(supermaplayer)
  
}

const addHeatMap = ()=>{

  const fakeData = {
    type: 'FeatureCollection',
    features: []
};

// 生成更多的随机点（这里生成1000个，可根据需要调整）
const numPoints = 1000;
const beijingCenterLon = 116.4; // 北京中心经度
const beijingCenterLat = 39.9; // 北京中心纬度
const range = 1; // 点分布范围（单位：度，这里表示以北京中心为圆心，1度范围内生成点）

for (let i = 0; i < numPoints; i++) {
    // 在以北京为中心的一定范围内生成随机坐标
    const randomLng = beijingCenterLon + (Math.random() * 2 - 1) * range;
    const randomLat = beijingCenterLat + (Math.random() * 2 - 1) * range;

    // 将经纬度坐标转换为3857投影坐标
    const [x, y] =fromLonLat([randomLng, randomLat], 'EPSG:3857');

    // 根据坐标生成热度值，这里可以根据距离北京中心的距离来生成热度
    const distanceToCenter = Math.sqrt((randomLng - beijingCenterLon) ** 2 + (randomLat - beijingCenterLat) ** 2);
    const heat = 100 / (1 + distanceToCenter);

    const feature = {
        type: 'Feature',
        geometry: {
            type: 'Point',
            coordinates: [x, y]
        },
        properties: {
            heat: heat
        }
    };
    fakeData.features.push(feature);
}

  // 创建热力图层的源
var heatmapSource = new VectorSource({
 // url: `https://restapi.amap.com/v3/heatmap/geo?key=${config.GDTK}&locations="116.3,39.9;116.4,39.8;116.2,39.95"`, // 替换{your_key}和{data}
 features: new GeoJSON().readFeatures(fakeData),
  format: new GeoJSON()
});

// 创建热力图层
var heatmapLayer = new Heatmap({
  source: heatmapSource,
  blur: 15,
  radius: 5,
  weight: function (feature) {
      return feature.get('heat');
  }
});

// 将热力图层添加到地图中
map.addLayer(heatmapLayer);
}
const showMap = (laycode) => {
  const layers = map.getLayers().getArray()
  layers.forEach((layer, index) => {
    if (layer.get('id') === laycode) {
      // 替换为你的图层名称
      mapFlag[laycode] = true;
      layer.setVisible(true);
    }
  })
}

const delMapLayer = (laycode, layerVisible) => {
  if (EarthQuakeYXC[laycode]) {
    delEarthQuakeYXC(laycode);
    return
  }
  const layers = map.getLayers().getArray();
  layers.forEach((layer, index) => {
    if (layer.get('id') === laycode) {
      // 替换为你的图层名称
      mapFlag[laycode] = false;
      layer.setVisible(false);
      // map.getLayers().removeAt(index) // 使用 removeAt 方法根据索引删除图层
    }
  })
}

let earthQuakeLonLatView = null;
//根据影响场确定初始范围
export const loadInitView = (id, version)=>{
  var query = {
    tableName: 'setting_seismic_influenceflied',
    fields:
      'uuid,earthquake_level,dz_intensity,long_x,short_y,data_source,remark,earth_quake_id,operate_time,trigger_type,model_id,category,operate_user_id,operate_dept_id,version,type,code,angle,intensity_show,intensity_china_show,area',
    filter: `earth_quake_id='${id}' AND version='${version}' `
  }
  earthQuakeLonLatView = null;
  onemap.listGeoJsonByTable(query).then((res) => {
    var geojson = JSON.parse(res.geodata.value)
    if(!geojson.features){
      toViewEarthQuakeCenter();
      return
    }  
    var tmpLayer = new VectorImageLayer({
      zIndex:99,
      declutter: true
    })
 
    var  geoarr =  new GeoJSON().readFeatures(geojson).filter(e=>e.values_.dz_intensity > 5);
    const vectorSource = new VectorSource({
      features: geoarr
    })
    
    if(geoarr && geoarr.length === 0){
      toViewEarthQuakeCenter()
      return
     }
    tmpLayer.setSource(vectorSource)
    earthQuakeLonLatView = tmpLayer;
    toViewEarthQuakeCenter()
  })
}
//获取地震影响场
let EarthQuakeYXC = {}

const loadEarthQuakeYXC = (id, layerCode, version) => {
  // id=624;
  var query = {
    tableName: 'setting_seismic_influenceflied',
    fields:
      'uuid,earthquake_level,dz_intensity,long_x,short_y,data_source,remark,earth_quake_id,operate_time,trigger_type,model_id,category,operate_user_id,operate_dept_id,version,type,code,angle,intensity_show,intensity_china_show,area',
    filter: `earth_quake_id='${id}' AND version='${version}' `
  }
  loadAllYXC(query,layerCode)
}


export const loadAllYXC =(query,layerCode) =>{
  onemap.listGeoJsonByTable(query).then((res) => {
    var geojson = JSON.parse(res.geodata.value)
    if(!geojson.features) return 
    
    var tmpLayer = new VectorImageLayer({
      zIndex:99,
      declutter: true
    })
    const vectorSource = new VectorSource({
      features: new GeoJSON().readFeatures(geojson).filter(e=>e.values_.dz_intensity > 5)
    })

    tmpLayer.setSource(vectorSource)
    vectorSource.forEachFeature((feature) => {
      let style = new Style({
        fill: new Fill({
          color: get2dColor(feature.values_.dz_intensity)
        }),
        stroke: new Stroke({
          color: 'rgba(197, 208, 218, 0.8)',
          width: 2
        }), 
             text: new Text({
          font: '22px sans-serif',
          text: convertToRoman(feature.values_.dz_intensity) +"度" ,
          fill: new Fill({
            color: [255, 0, 0, 1],
          }),
          offsetX: 45, // 根据文本字号等情况适当调整偏移量，使文本向右移动靠近要素右边缘
          // offsetY: 10, // 使文本向下移动靠近要素下边缘
          anchor: [0, 0.5], // 将锚点设置在文本中心位置，水平和垂直方向都居中对齐
          padding: [1, 1, 1, 1],
        }),
      })
      feature.setStyle(style)
    })
    map.addLayer(tmpLayer)
    EarthQuakeYXC[layerCode] = tmpLayer
    earthQuakeLonLatView = tmpLayer;
    map.getView().fit(tmpLayer.getSource().getExtent(), {
      padding: [100, 100, 100, 100], // 可选的填充，以确保要素不会被地图边缘截断
      duration: 1000 // 动画持续时间（以毫秒为单位）
    })
  })
}

function toViewEarthQuakeCenter (){
  if(earthQuakeLonLatView){
    map.getView().fit(earthQuakeLonLatView.getSource().getExtent(), {
      padding: [100, 100, 100, 100], // 可选的填充，以确保要素不会被地图边缘截断
      duration: 1000 // 动画持续时间（以毫秒为单位）
    })
  }else{
    // map.getView().setCenter(fromLonLat([store.earthquakeInfo.longitude,store.earthquakeInfo.latitude]))
    // map.getView().setZoom(8)
   
var view = map.getView();
 
// 设置地图中心的坐标
view.animate({
    center:transform([ store.earthquakeInfo.longitude,store.earthquakeInfo.latitude ], 'EPSG:4326','EPSG:3857')},{zoom : 12})

}
}
//数字转罗马数字
function convertToRoman(num) {
  let romanNumerals = [
      { value: 1000, symbol: "M" },
      { value: 900, symbol: "CM" },
      { value: 500, symbol: "D" },
      { value: 400, symbol: "CD" },
      { value: 100, symbol: "C" },
      { value: 90, symbol: "XC" },
      { value: 50, symbol: "L" },
      { value: 40, symbol: "XL" },
      { value: 10, symbol: "X" },
      { value: 9, symbol: "IX" },
      { value: 5, symbol: "V" },
      { value: 4, symbol: "IV" },
      { value: 1, symbol: "I" }
  ];
  let roman = "";
  for (let i = 0; i < romanNumerals.length; i++) {
      while (num >= romanNumerals[i].value) {
          roman += romanNumerals[i].symbol;
          num -= romanNumerals[i].value;
      }
  }
  return roman;
}

//罗马数字转数字
 function romanToNumber(roman) {
  const romanNumerals = {
    'I': 1,
    'V': 5,
    'X': 10,
    'L': 50,
    'C': 100,
    'D': 500,
    'M': 1000
  };
  let result = 0;
  for (let i = 0; i < roman.length; i++) {
    const currentValue = romanNumerals[roman[i]];
    const nextValue = roman[i + 1]? romanNumerals[roman[i + 1]] : 0;
    if (currentValue < nextValue) {
      result -= currentValue;
    } else {
      result += currentValue;
    }
  }
  return result;
}

//大屏烈度图
 const getGeoJson = (e,maps,color,text,max)=>{
  var geojson = JSON.parse(e)
  var tmpLayer = new VectorImageLayer({
    declutter: true
  })
  const vectorSource = new VectorSource({
    features: new GeoJSON().readFeatures(geojson)
  })

  tmpLayer.setSource(vectorSource)
  vectorSource.forEachFeature((feature) => {
    let style = new Style({
      fill: new Fill({
        color:getLM2dColor(text)
      }),
      stroke: new Stroke({
        color: 'rgba(197, 208, 218, 0.8)',
        width: 2
      }),
      text: new Text({
        font: '16px sans-serif',
        text:  text+"度"+"("+getLM2dtoNum(text)+"度)",
        fill: new Fill({
          color: [255, 0, 0, 1],
        }),
        offsetX: 5, 
        overflow: true //超出面的部分不显示
        // placement: "line", 
        // backgroundFill: new Fill({
        //   color: color,
        // }),
      }),
    })
    feature.setStyle(style)
  })
  maps.addLayer(tmpLayer)
if(max){
  maps.getView().fit(tmpLayer.getSource().getExtent(), {
    padding: [50, 50, 50, 50], // 可选的填充，以确保要素不会被地图边缘截断
    duration: 1000 // 动画持续时间（以毫秒为单位）
  })
}
}

export const toViewsCenter = (maps,lonlat)=>{
  maps.getView().setCenter(fromLonLat(lonlat))
  maps.getView().setZoom(8);
}

const delEarthQuakeYXC = (laycode) => {
  map.removeLayer(EarthQuakeYXC[laycode]);
  EarthQuakeYXC[laycode] = null;
}

export const get2dColor = (num)=>{
  var yxcColor = {
    11:"rgba(140, 0, 0, 0.8)",
    10:"rgba(168, 0, 0, 0.75)",
    9:"rgba(200, 40, 40, 0.7)",
    8:"rgba(255, 127, 127, 0.65)",
    7:"rgba(255, 190, 190, 0.6)",
    6:"rgba(255, 210, 218, 0.55)",
    5:"rgba(199, 252, 229, 0)",
    4:"rgba(199, 252, 229, 0)",
    3:"rgba(199, 252, 229, 0)",
    2:"rgba(199, 252, 229, 0)",
    1:"rgba(199, 252, 229, 0)",
    "default":"rgba(255, 210, 218, 0.2)"
    }
    return yxcColor[num] || yxcColor.default
}

const getLM2dColor = (str)=>{
  var yxcColor = {
    'Ⅺ':"rgba(140, 0, 0, 0.8)",
    'Ⅹ':"rgba(168, 0, 0, 0.75)",
    'Ⅸ':"rgba(200, 40, 40, 0.7)",
    'Ⅷ':"rgba(255, 127, 127, 0.65)",
    'Ⅶ':"rgba(255, 190, 190, 0.6)",
    'Ⅵ':"rgba(255, 210, 218, 0.55)",
    'Ⅴ':"rgba(199, 252, 229, 0)",
    'Ⅳ':"rgba(199, 252, 229, 0)",
    'Ⅲ':"rgba(199, 252, 229, 0)", 
    'Ⅱ':"rgba(199, 252, 229, 0)",
    'Ⅰ':"rgba(199, 252, 229, 0)",
    "default":"rgba(255, 210, 218, 0.2)"
    }
    return yxcColor[str] || yxcColor.default
}

export const getLM2dtoNum = (str)=>{
  var num = {
    'Ⅺ':11,
    'Ⅹ':10,
    'Ⅸ':9,
    'Ⅷ':8,
    'Ⅶ':7,
    'Ⅵ':6,
    'Ⅴ':5,
    'Ⅳ':4,
    'Ⅲ':3, 
    'Ⅱ':2,
    'Ⅰ':1,
    }
    return num[str] || 0
}

export const getColor = (type) => {
  if (type == "3d") {
    // 手动将RGBA值转换为Cesium.Color对象  
    const red = 254 / 255.0;   // 将0-255的RGB值转换为0-1的范围  
    const green = 229 / 255.0;
    const blue = 230 / 255.0;
    const alpha = 0.5;         // alpha值已经是0-1的范围  

    return new Cesium.Color(red, green, blue, alpha);
  }
  return 'rgba(254, 229, 230, 0.5)'
}



const surveyAreaAndLine = () => {
  let measureType = 'diatence'
  let vectorLayer = null
  let tipDiv = null
  let pointermoveEvent = null // 地图pointermove事件
  let sketchFeature = null // 绘制的要素
  let geometryListener = null // 要素几何change事件
  let measureResult = '0' // 测量结果
  let draw = null
  let layerArr = []

  const creatDraw = (type) => {
    let maxPoints = null
    if (measureType == 'angle') maxPoints = 3
    else maxPoints = null
    // 矢量图层源
    let vectorSource = new VectorSource({
      wrapX: false
    })
    // 矢量图层
    let vectorLayer = new VectorLayer({
      source: vectorSource,
      style: new Style({
        fill: new Fill({
          color: 'rgba(252, 86, 49, 0.1)'
        }),
        stroke: new Stroke({
          color: '#fc5531',
          width: 3
        }),
        image: new Circle({
          radius: 0,
          fill: new Fill({
            color: '#fc5531'
          })
        })
      }),
      name: '测量图层'
    })
    map.addLayer(vectorLayer)
    draw = new Draw({
      source: vectorSource,
      type: type,
      maxPoints: maxPoints,
      style: new Style({
        fill: new Fill({
          color: 'rgba(252, 86, 49, 0.1)'
        }),
        stroke: new Stroke({
          color: '#fc5531',
          lineDash: [10, 10],
          width: 3
        }),
        image: new Circle({
          radius: 0,
          fill: new Fill({
            color: '#fc5531'
          })
        })
      }),
      //   // 绘制时点击处理事件
      condition: (evt) => {
        // 测距时添加点标注
        if (measureResult != '0' && !map.getOverlayById(measureResult) && measureType == 'distence')
          creatMark(null, measureResult, measureResult).setPosition(evt.coordinate)
        return true
      }
    })
    map.addInteraction(draw)
    layerArr.push(vectorLayer)
    draw.on('drawstart', (e) => {
      sketchFeature = e.feature
      let proj = map.getView().getProjection()
      //******距离测量开始时*****//
      if (measureType == 'distence') {
        creatMark(null, '起点', 'start').setPosition(map.getCoordinateFromPixel(e.target.downPx_))
        tipDiv.innerHTML = '总长：0 m</br>单击确定地点，双击结束'
        geometryListener = sketchFeature.getGeometry().on('change', (evt) => {
          // measureResult = distenceFormat(
          //   getLength(evt.target, { projection: proj, radius: 6378137 })
          // )
          measureResult = distenceFormat(evt.target.getLength())
          tipDiv.innerHTML = '总长：' + measureResult + '</br>单击确定地点，双击结束'
        })
      }
      //******面积测量开始时*****//
      else if (measureType == 'area') {
        tipDiv.innerHTML = '面积：0 m<sup>2</sup></br>继续单击确定地点'
        geometryListener = sketchFeature.getGeometry().on('change', (evt) => {
          if (evt.target.getCoordinates()[0].length < 4)
            tipDiv.innerHTML = '面积：0m<sup>2</sup></br>继续单击确定地点'
          else {
            measureResult = formatArea( getArea(evt.target))  
          //  measureResult = formatArea(getArea(evt.target, { projection: proj, radius: 6378137 }))
            tipDiv.innerHTML = '面积：' + measureResult + '</br>单击确定地点，双击结束'
          }
        })
      }
      //******角度测量开始时*****//
      else if (measureType == 'angle') {
        tipDiv.innerHTML = '继续单击确定顶点'
        geometryListener = sketchFeature.getGeometry().on('change', (evt) => {
          if (evt.target.getCoordinates().length < 3) tipDiv.innerHTML = '继续单击确定顶点'
          else {
            measureResult = formatAngle(evt.target)
            tipDiv.innerHTML = '角度：' + measureResult + '</br>继续单击结束'
          }
        })
      }
    })

    draw.on('drawend', (e) => {
      // let closeBtn = document.createElement('span');
      // closeBtn.innerHTML = "×";
      // closeBtn.title = "清除测量"
      // closeBtn.style = "width: 10px;height:10px;line-height: 12px;text-align: center;border-radius: 5px;display: inline-block;padding: 2px;color: rgb(255, 68, 0);border: 2px solid rgb(255, 68, 0);background-color: rgb(255, 255, 255);font-weight: 600;position: absolute;top: -25px;right: -2px;cursor: pointer;";
      // closeBtn.addEventListener('click', () => {
      //   map.getLayers().remove(vectorLayer);
      //   // clearMeasure()
      // })
      //******距离测量结束时*****//
      if (measureType == 'distence') {
        //  creatMark(closeBtn, null, "close1").setPosition(e.feature.getGeometry().getLastCoordinate());
        creatMark(null, '总长：' + measureResult + '', 'length').setPosition(
          e.feature.getGeometry().getLastCoordinate()
        )
        map.removeOverlay(map.getOverlayById(measureResult))
      }
      //******面积测量结束时*****//
      else if (measureType == 'area') {
        creatMark(null, null, 'close2').setPosition(
          e.feature.getGeometry().getInteriorPoint().getCoordinates()
        )
        creatMark(null, '总面积：' + measureResult + '', 'area').setPosition(
          e.feature.getGeometry().getInteriorPoint().getCoordinates()
        )
      }
      //******角度测量结束时*****//
      else if (measureType == 'angle') {
        creatMark(closeBtn, null, 'close3').setPosition(e.feature.getGeometry().getCoordinates()[1])
        creatMark(null, '角度：' + measureResult + '', 'angle').setPosition(
          e.feature.getGeometry().getCoordinates()[1]
        )
      }
      // 停止测量
      stopMeasure()
    })
  }
  const measure = (type) => {
    if (draw != null) return false // 防止在绘制过程再创建测量
    measureType = type
    if (vectorLayer != null) clearMeasure()
    tipDiv = document.createElement('div')
    tipDiv.innerHTML = '单击确定起点'
    tipDiv.className = 'tipDiv'
    tipDiv.style =
      'width:auto;height:auto;padding:4px;border:1px solid #fc5531;font-size:12px;background-color:#fff;position:relative;top:60%;left:60%;font-weight:600;'

    let overlay = new Overlay({
      element: tipDiv,
      autoPan: false,
      positioning: 'bottom-center',
      id: 'tipLay',
      stopEvent: false //停止事件传播到地图
    })
    map.addOverlay(overlay)

    pointermoveEvent = map.on('pointermove', (evt) => {
      overlay.setPosition(evt.coordinate)
    })
    if (measureType == 'distence' || measureType == 'angle') {
      creatDraw('LineString')
    } else if (measureType == 'area') {
      creatDraw('Polygon')
    }
  }

  const creatMark = (markDom, txt, idstr) => {
    if (markDom == null) {
      markDom = document.createElement('div')
      markDom.innerHTML = txt
      markDom.style =
        'width:auto;height:auto;padding:4px;border:1px solid #fc5531;font-size:12px;background-color:#fff;position:relative;top:60%;left:60%;font-weight:600;'
    }
    let overlay = new Overlay({
      element: markDom,
      autoPan: false,
      positioning: 'bottom-center',
      id: idstr,
      stopEvent: false
    })
    map.addOverlay(overlay)
    return overlay
  }

  const distenceFormat = (length) => {
    let output
    if (length > 100) {
      output = Math.round((length / 1000) * 100) / 100 + ' ' + 'km' //换算成km单位
    } else {
      output = Math.round(length * 100) / 100 + ' ' + 'm' //m为单位
    }
    return output //返回线的长度
  }

  const formatArea = (area) => {
    let output
    if (area > 10000) {
      output = Math.round((area / 1000000) * 100) / 100 + ' ' + 'km<sup>2</sup>' //换算成km单位
    } else {
      output = Math.round(area * 100) / 100 + ' ' + 'm<sup>2</sup>' //m为单位
    }
    return output //返回多边形的面积
  }
  /**
   * 计算角度输出
   */
  const formatAngle = (line) => {
    var coordinates = line.getCoordinates()
    var angle = '0°'
    if (coordinates.length == 3) {
      const disa = getLength(
        new Feature({
          geometry: new LineString([coordinates[0], coordinates[1]])
        }).getGeometry(),
        {
          radius: 6378137,
          projection: map.getView().getProjection()
        }
      )

      const disb = getLength(
        new Feature({
          geometry: new LineString([coordinates[1], coordinates[2]])
        }).getGeometry(),
        {
          radius: 6378137,
          projection: map.getView().getProjection()
        }
      )

      const disc = getLength(
        new Feature({
          geometry: new LineString([coordinates[0], coordinates[2]])
        }).getGeometry(),
        {
          radius: 6378137,
          projection: map.getView().getProjection()
        }
      )
      var cos = (disa * disa + disb * disb - disc * disc) / (2 * disa * disb) // 计算cos值
      angle = (Math.acos(cos) * 180) / Math.PI // 角度值
      angle = angle.toFixed(2) // 结果保留两位小数
    }
    if (isNaN(angle)) return '0°'
    else return angle + '°' // 返回角度
  }
  /**
   * 停止测量
   */
  const stopMeasure = () => {
    tipDiv = null
    map.removeInteraction(draw) // 移除绘制组件
    draw = null
    map.removeOverlay(map.getOverlayById('tipLay')) // 移除动态提示框
    pointermoveEvent = null
    geometryListener = null
    measureResult = '0'
  }
  /**
   * 清除测量
   */
  const clearMeasure = () => {
    layerArr.forEach((layer) => {
      map.getLayers().remove(layer)
    })
    map.getOverlays().clear()
    //移除监听事件
    unByKey(pointermoveEvent) // 清除鼠标在地图的pointermove事件
    unByKey(geometryListener) // 清除绘制图像change事件
    pointermoveEvent = null
    geometryListener = null
    measureResult = '0'
  }

  return {
    measure,
    clearMeasure
  }
}

// 计算平面距离的函数，传入两个经纬度坐标数组
const computedDistance = (l1, l2) => {
  // 将经纬度坐标转换为平面坐标（这里假设使用Web Mercator投影，可根据实际情况调整投影方式）
  const point1 = transform([l1[0], l1[1]], 'EPSG:4326', 'EPSG:3857');
  const point2 = transform([l2[0], l2[1]], 'EPSG:4326', 'EPSG:3857');

  // 获取平面坐标的x、y值
  const x1 = point1[0];
  const y1 = point1[1];
  const x2 = point2[0];
  const y2 = point2[1];

  // 根据平面坐标距离公式（勾股定理扩展形式）计算距离
  const dx = x2 - x1;
  const dy = y2 - y1;
  const distance = Math.sqrt(dx * dx + dy * dy);

  // 将距离单位从米转换为千米并四舍五入取整
  const distanceInKilometers = distance / 1000;
  return Math.round(distanceInKilometers);
};

// let intervalId;

function createFlashingPoint(lonLat, mapExt) {
  // 创建闪烁的红色点样式
  const flashStyle = new Style({
    image: new Circle({
      radius: 10,
      fill: new Fill({ color: 'rgba(255,0,0,1)' }),
      stroke: new Stroke({ color: 'rgba(255,0,0,1)', width: 1 })
    })
  })

  // 创建点要素
  const point = new Feature({
    geometry: new Point(fromLonLat(lonLat,'EPSG:3857'))
  })

  // 将样式应用到点要素上
  point.setStyle(flashStyle)

  const vectorSource = new VectorSource()
  vectorSource.addFeature(point)
  const vectorLayer = new VectorLayer({
    zIndex: 9999,
    source: vectorSource
  })
  if (mapExt) {
    mapExt.addLayer(vectorLayer)
    mapExt.getView().setCenter(fromLonLat(lonLat))
    mapExt.getView().setZoom(8)
  } else {
    map.addLayer(vectorLayer)
    map.getView().setCenter(fromLonLat(lonLat))
    map.getView().setZoom(8)
  }


  // // 实现闪烁效果
  // let isVisible = true;
  // intervalId = setInterval(() => {
  //   isVisible =!isVisible;
  //   point.setStyle(isVisible? flashStyle : null);
  // }, 500);

  // return intervalId;
}

function createPointImg (lonLat,img, mapExt,flag){
  // 创建闪烁的红色点样式
  const flashStyle = new Style({
    image: new Icon({
      src: img,
      // anchor: [0.5, 0.5], // 设置图片锚点位置，这里表示图片中心水平对齐，底部垂直对齐
      scale: 0.7
  })
  })

  // 创建点要素
  const point = new Feature({
    geometry: new Point(fromLonLat(lonLat,'EPSG:3857'))
  })

  // 将样式应用到点要素上
  point.setStyle(flashStyle)

  const vectorSource = new VectorSource()
  vectorSource.addFeature(point)
  const vectorLayer = new VectorLayer({
    zIndex: 9999,
    source: vectorSource
  })
  if (mapExt) {
    mapExt.addLayer(vectorLayer)
  } else {
    map.addLayer(vectorLayer)
  }

  if(flag){
    mapExt.getView().setCenter(fromLonLat(lonLat))
    mapExt.getView().setZoom(8)
  }
}



function clearFlashingPoint(intervalId) {
  clearInterval(intervalId)
}

function createLine() {
  // 假设附近乡镇坐标（经纬度）转换为 EPSG:3857
  const nearbyTownLonLat = [121, 31]
  const nearbyTown = fromLonLat(nearbyTownLonLat, 'EPSG:3857')

  // 绘制线连接震中到附近乡镇
  const lineFeature = new Feature({
    geometry: new LineString([earthquakeCenter, nearbyTown])
  })
  const lineStyle = new Style({
    stroke: new Stroke({
      color: 'red',
      width: 2
    })
  })
  lineFeature.setStyle(lineStyle)
  const lineVectorSource = new VectorSource({
    features: [lineFeature]
  })
  const lineVectorLayer = new VectorLayer({
    source: lineVectorSource
  })
  map.addLayer(lineVectorLayer)
}

let earthQuakeRadiuLayer = null

function createEarthquakeRadiusLayer(r, earthquakeCenterLonLat) {
  const ranges = r
  ranges.sort((a, b) => b - a)
  const earthquakeCenter = fromLonLat(earthquakeCenterLonLat, 'EPSG:3857')
  let vectorSource = new VectorSource()
  ranges.forEach((range) => {
    const circle = new CircleGeometry(earthquakeCenter, range * 1000)
    const feature = new Feature({
      geometry: circle
    })
    let color
    if (range <= 10) {
      color = 'rgba(220,20,20,0.9)'
    } else if (range <= 20) {
      color = 'rgba(240,140,55,0.9)'
    } else if (range <= 50) {
      color = 'rgba(0,240,210,0.9)'
    } else {
      color = 'rgba(128,128,128,0.9)'
    }

    const style = new Style({
      // fill: new Fill({
      //     color: color
      // }),

      stroke: new Stroke({
        color: color,
        width: 3
      })
    })
    const stylePoint = new Style({
      image: new Circle({
        radius: 1,
        fill: new Fill({ color: 'rgba(255,0,0,1)' }),
        stroke: new Stroke({ color: 'rgba(255,0,0,1)', width: 1 })
      }),
      text: new Text({
        font: '12px sans-serif',
        text: range + "公里",
        fill: new Fill({
          color: [255, 255, 255, 1],
        }),
        backgroundFill: new Fill({
          color: color,
        }),
        padding: [1, 1, 1, 1],
      }),
    })
    //添加点
    // 获取圆心坐标

    // 定义中心点的经纬度和半径
    const centerLonLat = earthquakeCenterLonLat // 中心点的经纬度
    const radius = range * 1000 // 半径，单位是米

    // 将经纬度坐标转换为 Web Mercator 坐标
    const center = fromLonLat(centerLonLat)

    // 计算正东方的点坐标
    // 计算正东方的坐标
    const angle = 0 // 0度代表正东方
    const dx = radius * Math.cos((angle * Math.PI) / 180)
    const dy = radius * Math.sin((angle * Math.PI) / 180)

    // 得到正东方的点坐标
    const eastPoint = [center[0] + dx, center[1]] // y 不变，x 增加
    // 创建一个点要素并设置其坐标
    const pointFeature = new Feature({
      geometry: new Point(eastPoint)
    })
    pointFeature.setStyle(stylePoint)

    // 创建一个矢量数据源
    // const vectorSource = new ol.source.Vector({
    //   features: [pointFeature] // 将点要素添加到数据源
    // })
    feature.setStyle(style)
    vectorSource.addFeature(pointFeature)
    vectorSource.addFeature(feature)
  })

  const vecLayer = new VectorLayer({
    zIndex: 999,
    source: vectorSource
  })
  earthQuakeRadiuLayer = vecLayer
  map.addLayer(vecLayer)
}

function updateEarthquakeRadius(range, w) {
  earthQuakeRadiuLayer && map.removeLayer(earthQuakeRadiuLayer)
  createEarthquakeRadiusLayer(range, w)
}
export {
  LoadBaseLayers,
  AddGeoJsonLayer,
  AddMapLayer,
  MapStyle,
  MapColors,
  createPoint,
  addMapLayer,
  delMapLayer,
  surveyAreaAndLine,
  computedDistance,
  createFlashingPoint,
  createEarthquakeRadiusLayer,
  updateEarthquakeRadius,
  init4490,
  getGeoJson,
  addHeatMap,
  createPointImg,
  toViewEarthQuakeCenter
}
